package com.flyone.qybackend.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.flyone.qybackend.common.ErrorCode;
import com.flyone.qybackend.exception.BusinessException;
import com.flyone.qybackend.mapper.DiaryMapper;
import com.flyone.qybackend.model.dto.diary.DiarySaveRequest;
import com.flyone.qybackend.model.entity.*;
import com.flyone.qybackend.service.DiaryService;
import com.flyone.qybackend.utils.AipNIpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
* @author luoyifei
* @description 针对表【diary(帖子)】的数据库操作Service实现
* @createDate 2023-04-22 18:21:26
*/
@Service
@Slf4j
public class DiaryServiceImpl extends ServiceImpl<DiaryMapper, Diary>
    implements DiaryService{

    @Resource
    private AipNIpUtils aipNIpUtils;

    @Override
    public List<Diary> getDiaryWithDay(String date, Long userId) {
        QueryWrapper<Diary> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId",userId);
        List<Diary> diaryList = this.list(queryWrapper);
        if (CollectionUtil.isEmpty(diaryList)){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        return diaryList.stream().filter(diary -> {
            String createTime = new SimpleDateFormat("yyyyMMdd HH:mm:ss").format(diary.getCreateTime()).split(" ")[0];
            return date.equals(createTime);
        }).collect(Collectors.toList());
    }

    @Override
    public long saveWrite(DiarySaveRequest diarySaveRequest, long userId) {
        String content = diarySaveRequest.getContent();

        String accessToken = aipNIpUtils.getAccessToken();
        ATA ata = aipNIpUtils.sentimentClassify(content, accessToken);
        List<ATAItem> items = ata.getItems();

        Diary diary = new Diary();

        diary.setWeather(diarySaveRequest.getWeather());
        diary.setMood(diarySaveRequest.getMood());
        diary.setUserId(userId);
        diary.setPhotograph(diarySaveRequest.getPhotograph());
        diary.setTitle(diarySaveRequest.getTitle());
        diary.setContent(content);
        diary.setSentiment(items.get(0).getSentiment());
        diary.setConfidence(items.get(0).getConfidence());
        diary.setPositiveProb(items.get(0).getPositive_prob());
        diary.setNegativeProb(items.get(0).getNegative_prob());

        this.save(diary);

        return diary.getId();
    }

    @Override
    public boolean removeDiary(long diaryId, Long userId) {

        return removeById(diaryId);
    }

    @Override
    public boolean updateWrite(DiarySaveRequest diarySaveRequest, Long userId) {
        long diaryId = diarySaveRequest.getId();

        String accessToken = aipNIpUtils.getAccessToken();
        ATA ata = aipNIpUtils.sentimentClassify(diarySaveRequest.getContent(), accessToken);
        List<ATAItem> items = ata.getItems();

        Diary diary = new Diary();

        diary.setWeather(diarySaveRequest.getWeather());
        diary.setMood(diarySaveRequest.getMood());
        diary.setUserId(userId);
        diary.setPhotograph(diarySaveRequest.getPhotograph());
        diary.setTitle(diarySaveRequest.getTitle());
        diary.setContent(diarySaveRequest.getContent());
        diary.setSentiment(items.get(0).getSentiment());
        diary.setConfidence(items.get(0).getConfidence());
        diary.setPositiveProb(items.get(0).getPositive_prob());
        diary.setNegativeProb(items.get(0).getNegative_prob());

        QueryWrapper<Diary> updateWrapper = new QueryWrapper<>();
        updateWrapper.eq("id",diaryId);

        return update(diary, updateWrapper);
    }

    @Override
    public ScoreDiary getScoreWithDiary(int mouth, Long userId) {
        QueryWrapper<Diary> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId", userId).apply("MONTH(createTime)={0}", mouth);

        List<Diary> list = list(queryWrapper);
        if (CollectionUtil.isEmpty(list)){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        ScoreDiary scoreDiary = new ScoreDiary();
        //心情指数比率
        AtomicReference<Float> exponentialRatio = new AtomicReference<>((float) 0);
        Map<String, Integer> moodWithDay = new HashMap<>();

        list.forEach(diary -> {
           if (diary.getConfidence() >= 0.5){
               exponentialRatio.updateAndGet(v -> v + diary.getPositiveProb());
           }else if (diary.getConfidence() < 0.5){
               exponentialRatio.updateAndGet(v -> v + diary.getNegativeProb());
           }
           moodWithDay.put(new SimpleDateFormat("yyyyMMdd HH:mm:ss").format(diary.getCreateTime()).split(" ")[0], diary.getSentiment());
        });
        int Ratio = (int) (exponentialRatio.get() / list.size() * 100);

        scoreDiary.setMoodIndex(Ratio);
        scoreDiary.setMoodWithDay(moodWithDay);

        return scoreDiary;
    }

    @Override
    public int getDiaryCount(Long userId) {
        QueryWrapper<Diary> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId", userId);
        long count = count(queryWrapper);
        return (int) count;
    }

    @Override
    public RecordInfo getRecordInfo(Long userId) {
        QueryWrapper<Diary> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId", userId);
        List<Diary> diaryList = list(queryWrapper);
        HashSet<String> datesSet = new HashSet<>();
        int[] mouthChart = new int[12];
        int totalWords = 0;
        for (Diary diary : diaryList) {
            // 获取记录天数
            Date createTime = diary.getCreateTime();
            String date = new SimpleDateFormat("yyyy-MM-dd").format(createTime);
            datesSet.add(date);
            // 日期统计表
            String mouth = date.split("-")[1];
            mouthChart[Integer.parseInt(mouth)-1] += 1;
            // 获取记录总字数
            String content = diary.getContent();
            totalWords += content.length();
        }
        RecordInfo recordInfo = new RecordInfo();
        recordInfo.setRecordDay(datesSet.size());
        if (totalWords < 1000) {
            recordInfo.setTotalWord("<1K");
        } else {
            recordInfo.setTotalWord(totalWords / 1000 + "K");
        }
        recordInfo.setChartList(mouthChart);
        log.info(datesSet.toString());
        return recordInfo;
    }

}




